package br.mikhas.reflector.field;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * The {@link UnsafeFieldAccessor} uses hidden classes and methods which
 * provides direct access to field values.
 * 
 * @author Mikhail Domanoski
 * 
 */
public class UnsafeFieldAccessor extends FieldAccessor {

	private final long offset;
	private final static Unsafe unsafe;
	private final Class<?> type;
	private Object staticBase;

	static {
		unsafe = UnsafeGetter.getUnsafe();
	}

	public UnsafeFieldAccessor(Field field) {
		this.type = field.getType();

		if (Modifier.isStatic(field.getModifiers())) {
			this.staticBase = unsafe.staticFieldBase(field);
			this.offset = unsafe.staticFieldOffset(field);
		} else {
			this.offset = unsafe.objectFieldOffset(field);
		}
	}

	public Object get(Object target) {
		if (staticBase != null)
			target = staticBase;
		return unsafe.getValue(target, type, offset);
	}

	@Override
	public void set(Object target, Object value) {
		if (staticBase != null)
			target = staticBase;
		unsafe.setValue(target, type, offset, value);

	}
}
